关于 Kinect二代在 Win 系统下的配置
Kinect 是交互项目中非常流行的外设。因为配置相对简单,类库完善,交互项目中经常可以看到它的身影。本文主要介绍如何在 Openframeworks 中正确配置并使用 Kinect 二代传感器,同时提供参考代码。
下面是一些 Kinect 的使用场景,可以看到很多灵活的使用方法。
( 获取骨骼动作 )
https://vimeo.com/50229394 (The Treachery of Sanctuary)
( 从深度图获取位移信息 )
https://vimeo.com/28894641(作者:martin gautron)
( 从深度图获取触摸信息:投影 + Kinect )
https://vimeo.com/20372307(作者:Przemek Jaworski)
简单对比 - Kinect 1代 Vs Kinect 2代
( Kinect 1 代 )
( Kinect 2 代 )
Kinect 是微软旗下的游戏主机 xbox 的外设产品。一共出了两代。而 Kinect 2 代相比 1 代在硬件性能上的提升非常明显。
传感器的分辨率更高,识别更稳定。深度传感器分辨率从 320×240 升级到 512×424。RGB 摄像头分辨率从 640×480 升级到 1920×1080
可获取更多关节,20 个关节升级到 25 个关节。(Kinect1插件中经测试实际可获取的关节数为 15 个)
提升可同时识别的人物数量。从 2 个到 6 个
从个人的使用感受而言,在识别的准确度与稳定性上,2代比1代至少提升了一倍,动作延迟变得更小。虽然二代的性能非常强大,却有一个缺点,无论你使用的是 Processing 还是 Openframeworks,它只能够在 Windows 系统下使用,( Macbook 上虽然可以使用,但也必须安装 win 系统)。相比之下,Kinect 1 代是可以同时支持 osx 和 win ,使用和配置也更简单。如果使用场景对识别精度要求不高,更推荐使用 Kinect 1 代。
如何在 Windows 上使用 Kinect 2 代
Kinect 2 代的配置有不少坑,并不是直接下载插件就能一步到位解决问题。下面根据个人的一些使用经验,整理常见的问题。
插件 ofxKinectForWindows2 的使用
在使用插件之前,我们需要先安装 Kinect2 代的 SDK。这是官网下载链接 (https://www.microsoft.com/en-us/download/details.aspx?id=44561)
接下来需要使用到的插件就是 ofxKinectForWindows2 。它是一个支持 Kinect 2 代的 OF 插件。涵盖了 Kinect 的基本功能。
官方介绍:
Features
Currently lets you:
● Grab all the image streams (color, depth, IR, long exposure IR, body index)
● Generate a 3D ofMesh (point cloud or stitched mesh) with texture coordinates
● Track bodies (skeleton points, bone maps)
● Transfer coordinates
Currently doesn’t support:
● Audio
● Some remapping functions
使用方式 1 - 运行插件的自带实例
1.首先,从github 中下载插件(链接:https://github.com/elliotwoods/ofxKinectForWindows2。)下载后放到 addons 文件夹中,并更名为 ofxKinectForWindows2 。同时保证文件夹打开后,可以直接看到各个带 example 开头的文件。
2.一般进行到这里。大部分插件中的范例打开后,直接编译就能运行。但 ofxKinectForWindows2 还不行。如果你直接打开自带实例:exampleBodyIndexColor。它会出现下面的报错提示:
Severity Code Description Project File Line Suppression State
Error C3861 'ofRotateDeg': identifier not found ofxKinectForWindows2Lib d:\of_v0.9.8_vs_release\of_v0.9.8_vs_release\addons\ofxkinectforwindows2\src\ofxkinectforwindows2\device.cpp 370
Severity Code Description Project File Line Suppression State
Error LNK1104 cannot open file 'D:\of_v0.9.8_vs_release\of_v0.9.8_vs_release\addons\ofxKinectForWindows2\exampleBodyIndexColor\bin\ofxKinectForWindows2Lib.lib' exampleBodyIndexColor D:\of_v0.9.8_vs_release\of_v0.9.8_vs_release\addons\ofxKinectForWindows2\exampleBodyIndexColor\LINK 1
3.具体解决方法可以查看这里(https://github.com/elliotwoods/ofxKinectForWindows2/issues/77)
。里面提到下载插件时,需要选择 tag 为 0.90 的 addons ,不能直接使用 master)
将下载后的插件,改好文件名放进 addons(去掉 0.90 的后缀),直接打开 example 并选择 release 模式,即可运行。
使用方式 2 - 创建新项目,或在已有的项目中使用插件
如果你使用 Project Generator 自行创建一个新的空实例,再选择添加插件 ofxKinectForWindows2。此时直接运行实例,即使你不写任何代码。它还是会出现许多 errors 提示。这种情况可以按以下方法解决。
参考链接(https://github.com/elliotwoods/ofxKinectForWindows2/issues/52)
核心步骤摘录:
Q: I’ve been struggling with the exact same issue. A new project created using the Project Generator would throw the Kinect.h error. Here is how I solved it using VS2015 - hopefully it helps someone else.
● Install Kinect SDK (possible restart required)
● Download add-on
● Generate a new project using Project Generator and add ofxKinectForWindows2 addon
● Open project.In solution explorer - right click on Solution and choose Add -> Existing Project.Navigate to the addon\ofxKinectForWindows2\ofxKinectForWindows2Lib and choose the .vcxproj
( 注意:这步是右键 Solution,而不是 Project,否则后续会编译不成功 )
● In solution explorer - right click on your project Add -> Reference…
Check/enable ofxKinectForWindows2Lib。This next bit is where I stumbled just because I don’t know VS2015.You must add the add-on property file to your solution: View -> Other Windows -> Property Manager
● Click on the icon with a green plus in the Property Manager (Add existing prop sheet) Browse to addons\ofxKinectForWindows2\ofxKinectForWindows2.props
Compile and everything should work.
按以上方法添加好文件后,点编译就能正常通过。现在只要参考范例中 Kinect 的使用代码,把它运用在自己创建的项目工程中即可。
常用代码
结合插件 ofxKinectForWindows2,可以做出许多有趣的项目。插件里自带的第一个 example,就非常直观地展示各个传感器可获取的信息。
上面是 example 的运行效果。左上角图像是未处理的原始深度信息,大多数情况下是黑色的。左下角图像是正常的深度图,但需要较近的距离才会显示出丰富的灰度。右上角图像是 RGB 摄像头拍摄到的图像,同时附带了骨骼识别并使用特定函数 mapping 到画面上。右下角的图像是对人物抠像处理的黑白图,可以获取轮廓剪影。
要了解如何使用基本的传感器信息,只要查看 example 中相关的代码即可。如果你希望准确地获取骨骼中某个节点的位置坐标,手部的识别状态。下面整理了一段关键代码以供参考
int numBodiesTracked = 0; // 被识别的人数
auto& bodies = kinect.getBodySource()->getBodies();
for (auto& body : bodies) {
if (body.tracked) {
//cout << body.joints.size() << endl; // 关节数量为 25
ofColor color(200, 100, 100);
int index = 0;
for (const auto & joint : body.joints) {
color.setHueAngle((index * 50) % 360);
ofSetColor(color);
float r = 5; // 圆点半径
/*
index 值参考
JointType_SpineBase = 0, // 胯部
JointType_SpineMid = 1, // 胸口
JointType_Neck = 2, // 颈
JointType_Head = 3, // 头(最顶端节点)
JointType_ShoulderLeft = 4, // 左肩
JointType_ElbowLeft = 5, // 左肘
JointType_WristLeft = 6, // 左手腕
JointType_HandLeft = 7, // 左手指到左手掌的衔接处(接近掌心)
JointType_ShoulderRight = 8, // 右肩
JointType_ElbowRight = 9, // 右肘
JointType_WristRight = 10, // 右手腕
JointType_HandRight = 11, // 右手指到右手掌的衔接处(接近掌心)
JointType_HipLeft = 12, // 左臀
JointType_KneeLeft = 13, // 左膝
JointType_AnkleLeft = 14, // 左脚踝
JointType_FootLeft = 15, // 左脚掌
JointType_HipRight = 16, // 右臀
JointType_KneeRight = 17, // 右膝
JointType_AnkleRight = 18, // 右脚踝
JointType_FootRight = 19, // 右脚掌
JointType_SpineShoulder = 20, // 喉部下方(与肩平齐)
JointType_HandTipLeft = 21, // 左手四指末端
JointType_ThumbLeft = 22, // 左手拇指
JointType_HandTipRight = 23, // 右手四指末端
JointType_ThumbRight = 24, // 右手拇指
*/
// 获取右手坐标
if (index == 11 && numBodiesTracked == 0) {
/*
getPositionInWorld() 获取指定节点的世界坐标
世界坐标的位置范围参考,单位大致是 米
*/
ofSetColor(255);
font.drawString(ofToString(joint.second.getPositionInWorld()), 50, 50);
// 显示左手的手部状态 0:未知 1:未被追踪 2:张手 3:拳头 4:剪刀手
font.drawString("leftHand:" + ofToString(body.leftHandState), 50, 150);
// 显示右手的手部状态
font.drawString("rightHand:" + ofToString(body.rightHandState), 50, 250);
ofSetColor(0, 255, 0);
}
else {
ofSetColor(255, 0, 0);
}
// 手动绘制节点坐标,通过函数 getPositionInDepthMap() 获取的坐标与深度图的原始比例是重合的, 512 * 424
ofDrawCircle(joint.second.getPositionInDepthMap(), r);
ofSetColor(255);
ofDrawBitmapString(ofToString(index), joint.second.getPositionInDepthMap().x, joint.second.getPositionInDepthMap().y);
index++;
}
numBodiesTracked++;
}
}
End
关于 Kinect 2 代的介绍就到这里。最后有一点需要注意。不同的插件版本或是 OF 版本,遇到的情况都有可能不一样。上文提到的错误信息是在最新的 0.98 版下遇到的。如有遇到其他问题,我们都可以通过下面三个路径寻找到解决方案。(1)google ,(2)of官方论坛,(3)github。一般插件相关的使用报错问题,github 上是最全的。结合关键字,可以最快找到答案
相关链接
Kinect V2 的API 文档链接:
( https://msdn.microsoft.com/en-us/library/windowspreview.kinect.aspx )